@@ -0,0 +1,23 @@  | 
            ||
| 1 | 
                +# Generated by Django 3.2.8 on 2024-08-08 07:59  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import migrations, models  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +class Migration(migrations.Migration):  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                + dependencies = [  | 
            |
| 9 | 
                +        ('account', '0063_auto_20240529_1656'),
               | 
            |
| 10 | 
                + ]  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + operations = [  | 
            |
| 13 | 
                + migrations.AddField(  | 
            |
| 14 | 
                + model_name='lensmaninfo',  | 
            |
| 15 | 
                + name='identity_card_name',  | 
            |
| 16 | 
                + field=models.CharField(blank=True, help_text='身份证姓名', max_length=32, null=True, verbose_name='identity_card_name'),  | 
            |
| 17 | 
                + ),  | 
            |
| 18 | 
                + migrations.AddField(  | 
            |
| 19 | 
                + model_name='lensmaninfo',  | 
            |
| 20 | 
                + name='identity_card_number',  | 
            |
| 21 | 
                + field=models.CharField(blank=True, help_text='身份证号', max_length=32, null=True, verbose_name='identity_card_number'),  | 
            |
| 22 | 
                + ),  | 
            |
| 23 | 
                + ]  | 
            
                @@ -394,6 +394,10 @@ class LensmanInfo(BaseModelMixin):  | 
            ||
| 394 | 394 | 
                integral_start_date = models.DateField(_(u'start_date'), blank=True, null=True, help_text=u'积分开始日期')  | 
            
| 395 | 395 | 
                integral_end_date = models.DateField(_(u'start_date'), blank=True, null=True, help_text=u'积分截止日期')  | 
            
| 396 | 396 | 
                 | 
            
| 397 | 
                + # 身份证信息  | 
            |
| 398 | 
                + identity_card_number = models.CharField(_(u'identity_card_number'), max_length=32, blank=True, null=True, help_text=u'身份证号')  | 
            |
| 399 | 
                + identity_card_name = models.CharField(_(u'identity_card_name'), max_length=32, blank=True, null=True, help_text=u'身份证姓名')  | 
            |
| 400 | 
                +  | 
            |
| 397 | 401 | 
                class Meta:  | 
            
| 398 | 402 | 
                verbose_name = _(u'LensmanInfo')  | 
            
| 399 | 403 | 
                verbose_name_plural = _(u'LensmanInfo')  | 
            
                @@ -0,0 +1,20 @@  | 
            ||
| 1 | 
                +from django.conf import settings  | 
            |
| 2 | 
                +from django_logit import logit  | 
            |
| 3 | 
                +from django_response import response  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from kodo.decorators import check_admin  | 
            |
| 6 | 
                +from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +@logit(res=True)  | 
            |
| 9 | 
                +@check_admin  | 
            |
| 10 | 
                +def add_lensman_contribution_income_api(request, administrator):  | 
            |
| 11 | 
                +    contrbution_id = request.POST.get('contribution_id', '')
               | 
            |
| 12 | 
                +    lensman_id = request.POST.get('lensman_id', '')
               | 
            |
| 13 | 
                +    activity_id = request.POST.get('activity_id', '')
               | 
            |
| 14 | 
                +    user_id = request.POST.get('user_id', '')
               | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                +    amount = int(request.POST.get('amount', '0'))
               | 
            |
| 17 | 
                +  | 
            |
| 18 | 
                +    LensmanContributionActivityIncomeExpensesInfo.objects.update_or_create(contrbution_id=contrbution_id, lensman_id=lensman_id, activity_id=activity_id, user_id=user_id, defaults={'amount': amount})
               | 
            |
| 19 | 
                +  | 
            |
| 20 | 
                + return response(200, '增加摄影师投稿收入成功')  | 
            
                @@ -0,0 +1,31 @@  | 
            ||
| 1 | 
                +from django.conf import settings  | 
            |
| 2 | 
                +from django_logit import logit  | 
            |
| 3 | 
                +from django_response import response  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from kodo.decorators import check_admin  | 
            |
| 6 | 
                +from apps.contract.models import LensmanContributionContractInfo  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +@logit(res=True)  | 
            |
| 10 | 
                +@check_admin  | 
            |
| 11 | 
                +def get_signed_contribtion_contract_file_api(request, administrator):  | 
            |
| 12 | 
                +    contribution_id = request.POST.get('contribution_id', '')
               | 
            |
| 13 | 
                +    user_id = request.POST.get('user_id', '')
               | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + contract = LensmanContributionContractInfo.objects.filter(contribution_id=contribution_id, user_id=user_id).first()  | 
            |
| 16 | 
                +  | 
            |
| 17 | 
                +    operator =  {
               | 
            |
| 18 | 
                + "UserId": settings.CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID  | 
            |
| 19 | 
                + }  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                + BusinessType = 'FLOW'  | 
            |
| 22 | 
                + BusinessIds = [contract.flow_id]  | 
            |
| 23 | 
                + FileType = 'PDF'  | 
            |
| 24 | 
                + UrlTtl = '86400' # 过期时间  | 
            |
| 25 | 
                +  | 
            |
| 26 | 
                + # TODO: 获取合同文件 https://qian.tencent.com/developers/companyApis/templatesAndFiles/DescribeFileUrls  | 
            |
| 27 | 
                + FileUrls = []  | 
            |
| 28 | 
                +  | 
            |
| 29 | 
                +    return response(200, data={
               | 
            |
| 30 | 
                + 'file_url': FileUrls[0].Url  | 
            |
| 31 | 
                + })  | 
            
                @@ -0,0 +1,131 @@  | 
            ||
| 1 | 
                +from django.conf import settings  | 
            |
| 2 | 
                +from django_logit import logit  | 
            |
| 3 | 
                +from django_response import response  | 
            |
| 4 | 
                +from TimeConvert import TimeConvert as tc  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +from apps.contract.models import LensmanContributionContractInfo  | 
            |
| 7 | 
                +from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo  | 
            |
| 8 | 
                +from account.models import LensmanInfo  | 
            |
| 9 | 
                +from member.models import MemberActivityContributionInfo  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                +@logit(res=True)  | 
            |
| 13 | 
                +def get_contribtion_contract_api(request):  | 
            |
| 14 | 
                +    user_id = request.POST.get('user_id', '')
               | 
            |
| 15 | 
                +    lensman_id = request.POST.get('lensman_id', '')
               | 
            |
| 16 | 
                +    activity_id = request.POST.get('activity_id', '')
               | 
            |
| 17 | 
                +    contribtuon_id = request.POST.get('contribtuon_id', '')
               | 
            |
| 18 | 
                +  | 
            |
| 19 | 
                + lensman = LensmanInfo.objects.get(lensman_id=lensman_id)  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                + contract, _ = LensmanContributionContractInfo.objects.update_or_create(  | 
            |
| 22 | 
                + user_id=user_id, lensman_id=lensman_id, activity_id=activity_id, contribtuon_id=contribtuon_id)  | 
            |
| 23 | 
                +  | 
            |
| 24 | 
                + file_ids = upload_contribution_images(contribtuon_id)  | 
            |
| 25 | 
                +  | 
            |
| 26 | 
                +    operator =  {
               | 
            |
| 27 | 
                + "UserId": settings.CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID  | 
            |
| 28 | 
                + }  | 
            |
| 29 | 
                +  | 
            |
| 30 | 
                + flow_id = create_contribution_contract_flow(lensman, operator)  | 
            |
| 31 | 
                + contract.flow_id = flow_id  | 
            |
| 32 | 
                + contract.save()  | 
            |
| 33 | 
                +  | 
            |
| 34 | 
                + document_id, fields = create_contribution_contract_document(lensman, file_ids, flow_id, operator)  | 
            |
| 35 | 
                + contract.contract_content_fields = fields  | 
            |
| 36 | 
                + contract.document_id = document_id  | 
            |
| 37 | 
                + contract.save()  | 
            |
| 38 | 
                +  | 
            |
| 39 | 
                + # TODO : 发起签署流程  | 
            |
| 40 | 
                + start_contribution_contract_flow(flow_id, operator)  | 
            |
| 41 | 
                +  | 
            |
| 42 | 
                + scheme_url = get_contribtion_contract_sign_mppath(operator, lensman, flow_id)  | 
            |
| 43 | 
                +  | 
            |
| 44 | 
                +    return response(200, data={
               | 
            |
| 45 | 
                + 'contract': contract.mpdata,  | 
            |
| 46 | 
                + 'scheme_url': scheme_url  | 
            |
| 47 | 
                + })  | 
            |
| 48 | 
                +  | 
            |
| 49 | 
                +  | 
            |
| 50 | 
                +def upload_contribution_images(contribtuon_id):  | 
            |
| 51 | 
                + # TODO : 上传MemberActivityContributionInfo图片 https://qian.tencent.com/developers/companyApis/templatesAndFiles/UploadFiles  | 
            |
| 52 | 
                +  | 
            |
| 53 | 
                + contribtuon = MemberActivityContributionInfo.objects.get(contribtuon_id=contribtuon_id)  | 
            |
| 54 | 
                +  | 
            |
| 55 | 
                + # 返回图片的 file_ids  | 
            |
| 56 | 
                + return []  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                +  | 
            |
| 59 | 
                +def create_contribution_contract_flow(lensman, Operator):  | 
            |
| 60 | 
                + # TODO : 创建签署流程 https://qian.tencent.com/developers/companyApis/startFlows/CreateFlow  | 
            |
| 61 | 
                +  | 
            |
| 62 | 
                + # 创建签署流程参数 Operator  | 
            |
| 63 | 
                + FlowName = lensman.identity_card_name + "的投稿合同" + tc.local_string(format='%Y%m%d')  | 
            |
| 64 | 
                + FlowType = '活动投稿授权书'  | 
            |
| 65 | 
                +    Approvers = [{
               | 
            |
| 66 | 
                + "ApproverType": "1",  | 
            |
| 67 | 
                + "Required": "true",  | 
            |
| 68 | 
                + "NotifyType": "none",  | 
            |
| 69 | 
                + "ApproverMobile": lensman.phone,  | 
            |
| 70 | 
                + "ApproverName": lensman.identity_card_name,  | 
            |
| 71 | 
                + "ApproverIdCardNumber": lensman.identity_card_number,  | 
            |
| 72 | 
                + }]  | 
            |
| 73 | 
                +  | 
            |
| 74 | 
                + # 创建签署流程返回值 FlowId  | 
            |
| 75 | 
                + return ''  | 
            |
| 76 | 
                +  | 
            |
| 77 | 
                +  | 
            |
| 78 | 
                +def create_contribution_contract_document(lensman, contribtuon_id, file_ids, FlowId, Operator):  | 
            |
| 79 | 
                + # TODO : 创建电子签文档 https://qian.tencent.com/developers/companyApis/startFlows/CreateDocument  | 
            |
| 80 | 
                +  | 
            |
| 81 | 
                + income = LensmanContributionActivityIncomeExpensesInfo.objects.get(contribtuon_id=contribtuon_id, lensman_id=lensman.lensman_id)  | 
            |
| 82 | 
                +  | 
            |
| 83 | 
                + # 创建电子文档参数 Operator FlowId  | 
            |
| 84 | 
                + TemplateId = settings.CONTRACT_LENSMAN_CONTRIBUTION_TEMPLATE_ID  | 
            |
| 85 | 
                +  | 
            |
| 86 | 
                +    FormFields = [{
               | 
            |
| 87 | 
                + "ComponentName": "ComponentId_0",  | 
            |
| 88 | 
                + "ComponentValue": lensman.identity_card_name  | 
            |
| 89 | 
                +    }, {
               | 
            |
| 90 | 
                + "ComponentName": "ComponentId_1",  | 
            |
| 91 | 
                + "ComponentValue": lensman.identity_card_number,  | 
            |
| 92 | 
                +    }, {
               | 
            |
| 93 | 
                + "ComponentName": "ComponentId_2",  | 
            |
| 94 | 
                + "ComponentValue": income.amount,  | 
            |
| 95 | 
                +    }, {
               | 
            |
| 96 | 
                + "ComponentName": "ComponentId_3",  | 
            |
| 97 | 
                + "ComponentValue": "",  | 
            |
| 98 | 
                + }]  | 
            |
| 99 | 
                +  | 
            |
| 100 | 
                + for i, file_id in enumerate(file_ids):  | 
            |
| 101 | 
                +        FormFields.append({
               | 
            |
| 102 | 
                + "ComponentName": "ComponentId_" + str(37 + i),  | 
            |
| 103 | 
                + "ComponentValue": file_id,  | 
            |
| 104 | 
                + })  | 
            |
| 105 | 
                +  | 
            |
| 106 | 
                + # 返回创建电子文档 DocumentId  | 
            |
| 107 | 
                + return '', FormFields  | 
            |
| 108 | 
                +  | 
            |
| 109 | 
                +  | 
            |
| 110 | 
                +def start_contribution_contract_flow(FlowId, Operator):  | 
            |
| 111 | 
                + # TODO : 发起签署流程 https://qian.tencent.com/developers/companyApis/startFlows/StartFlow  | 
            |
| 112 | 
                +  | 
            |
| 113 | 
                + # 发起签署流程参数 Operator FlowId  | 
            |
| 114 | 
                +  | 
            |
| 115 | 
                + #  | 
            |
| 116 | 
                + return ''  | 
            |
| 117 | 
                +  | 
            |
| 118 | 
                +  | 
            |
| 119 | 
                +def get_contribtion_contract_sign_mppath(Operator, lensman, FlowId):  | 
            |
| 120 | 
                + # TODO : 获取签署链接 https://qian.tencent.com/developers/companyApis/startFlows/CreateSchemeUrl  | 
            |
| 121 | 
                +  | 
            |
| 122 | 
                + Name = lensman.identity_card_name  | 
            |
| 123 | 
                + Mobile = lensman.phone  | 
            |
| 124 | 
                + IdCardType = 'ID_CARD'  | 
            |
| 125 | 
                + IdCardNumber = lensman.identity_card_number  | 
            |
| 126 | 
                + EndPoint = 'APP'  | 
            |
| 127 | 
                + PathType = '1' #腾讯电子签小程序流程合同的详情页  | 
            |
| 128 | 
                + AutoJumpBack = 'true' #签署完成会自动跳转回来  | 
            |
| 129 | 
                +  | 
            |
| 130 | 
                + # 返回 SchemeUrl  | 
            |
| 131 | 
                + return ''  | 
            
                @@ -0,0 +1,12 @@  | 
            ||
| 1 | 
                +from django.conf.urls import include, url  | 
            |
| 2 | 
                +from api.lensman import contract_admin_views, contract_mp_views, activity_admin_views  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +urlpatterns = [  | 
            |
| 5 | 
                + url(r'^mp/lensman/contribution/contract/get$', contract_mp_views.get_contribtion_contract_api, name='get_contribtion_contract_api'),  | 
            |
| 6 | 
                +]  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +urlpatterns += [  | 
            |
| 9 | 
                + url(r'^admin/lensman/contribution/contract/file/get$', contract_admin_views.get_signed_contribtion_contract_file_api, name='get_signed_contribtion_contract_file_api'),  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                + url(r'^admin/lensman/contribution/income/add$', activity_admin_views.add_lensman_contribution_income_api, name='add_lensman_contribution_income_api'),  | 
            |
| 12 | 
                +]  | 
            
                @@ -384,4 +384,7 @@ urlpatterns += [  | 
            ||
| 384 | 384 | 
                url(r'^admin/lensman/update$', lensman_admin_views.lensman_update, name='admin_lensman_update'),  | 
            
| 385 | 385 | 
                url(r'^admin/lensman/integral/list$', lensman_admin_views.lensman_integral_list, name='admin_lensman_integral_list'),  | 
            
| 386 | 386 | 
                url(r'^admin/lensman/integral/update$', lensman_admin_views.lensman_integral_update, name='admin_lensman_integral_update'),  | 
            
| 387 | 
                -]  | 
            |
| 387 | 
                +  | 
            |
| 388 | 
                +    url(r'', include(('api.lensman.lensman_urls', 'lensman'), namespace='lensman')),
               | 
            |
| 389 | 
                +]  | 
            |
| 390 | 
                +  | 
            
                @@ -0,0 +1,3 @@  | 
            ||
| 1 | 
                +from django.contrib import admin  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Register your models here.  | 
            
                @@ -0,0 +1,6 @@  | 
            ||
| 1 | 
                +from django.apps import AppConfig  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +class ContractConfig(AppConfig):  | 
            |
| 5 | 
                + default_auto_field = 'django.db.models.BigAutoField'  | 
            |
| 6 | 
                + name = 'apps.contract'  | 
            
                @@ -0,0 +1,41 @@  | 
            ||
| 1 | 
                +# Generated by Django 3.2.8 on 2024-08-09 04:36  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import migrations, models  | 
            |
| 4 | 
                +import django_models_ext.fileext  | 
            |
| 5 | 
                +import jsonfield.fields  | 
            |
| 6 | 
                +import shortuuidfield.fields  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +class Migration(migrations.Migration):  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                + initial = True  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + dependencies = [  | 
            |
| 14 | 
                + ]  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                + operations = [  | 
            |
| 17 | 
                + migrations.CreateModel(  | 
            |
| 18 | 
                + name='LensmanContributionContractInfo',  | 
            |
| 19 | 
                + fields=[  | 
            |
| 20 | 
                +                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 21 | 
                +                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 22 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 23 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 24 | 
                +                ('contract_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='合同唯一标识', max_length=22, null=True, unique=True)),
               | 
            |
| 25 | 
                +                ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
               | 
            |
| 26 | 
                +                ('lensman_id', models.CharField(blank=True, db_index=True, help_text='摄影师唯一标识', max_length=32, null=True, verbose_name='lensman_id')),
               | 
            |
| 27 | 
                +                ('activity_id', models.CharField(blank=True, db_index=True, help_text='活动唯一标识', max_length=32, null=True, verbose_name='activity_id')),
               | 
            |
| 28 | 
                +                ('contribution_id', models.CharField(blank=True, db_index=True, help_text='活动投稿唯一标识', max_length=32, null=True, verbose_name='contribution_id')),
               | 
            |
| 29 | 
                +                ('contract_content_fields', jsonfield.fields.JSONField(blank=True, help_text=' 合同内容字段', null=True, verbose_name='contract_content_fields')),
               | 
            |
| 30 | 
                +                ('contract_file', models.FileField(blank=True, help_text='图片', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='contract_file')),
               | 
            |
| 31 | 
                +                ('flow_id', models.CharField(blank=True, help_text='电子签流程ID', max_length=128, null=True, verbose_name='flow_id')),
               | 
            |
| 32 | 
                +                ('document_id', models.CharField(blank=True, help_text='电子签文档ID', max_length=128, null=True, verbose_name='document_id')),
               | 
            |
| 33 | 
                +                ('contract_status', models.IntegerField(choices=[(1, '合同创建'), (2, '合同签署中'), (3, '合同拒签'), (4, '合同签署完成'), (5, '合同流签(合同过期)'), (6, '合同撤回'), (8, '合同待填写'), (21, '解除协议(已解除)'), (16, '合同已失效')], db_index=True, default=1, help_text='合同签署状态', verbose_name='contract_status')),
               | 
            |
| 34 | 
                +                ('approve_status', models.IntegerField(choices=[(2, '待签署'), (7, '待签署'), (3, '已签署'), (4, '拒绝'), (5, '过期没人处理'), (6, '流程已撤回'), (8, '合同待填写'), (9, '流程已终止'), (10, '填写完成'), (15, '解除协议(已解除)'), (15, '已转他人处理')], db_index=True, default=2, help_text='签署人签署状态', verbose_name='approve_status')),
               | 
            |
| 35 | 
                + ],  | 
            |
| 36 | 
                +            options={
               | 
            |
| 37 | 
                + 'verbose_name': '摄影师投稿合同信息',  | 
            |
| 38 | 
                + 'verbose_name_plural': '摄影师投稿合同信息',  | 
            |
| 39 | 
                + },  | 
            |
| 40 | 
                + ),  | 
            |
| 41 | 
                + ]  | 
            
                @@ -0,0 +1,91 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import models  | 
            |
| 4 | 
                +from django.utils.translation import ugettext_lazy as _  | 
            |
| 5 | 
                +from django_models_ext import BaseModelMixin, upload_file_path, upload_path  | 
            |
| 6 | 
                +from jsonfield import JSONField  | 
            |
| 7 | 
                +from shortuuidfield import ShortUUIDField  | 
            |
| 8 | 
                +from TimeConvert import TimeConvert as tc  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                +from utils.qiniucdn import qiniu_file_url  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                +# Create your models here.  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +class LensmanContributionContractInfo(BaseModelMixin):  | 
            |
| 16 | 
                + CONTRACT_STATUS_TUPLE = (  | 
            |
| 17 | 
                + (1, u'合同创建'),  | 
            |
| 18 | 
                + (2, u'合同签署中'),  | 
            |
| 19 | 
                + (3, u'合同拒签'),  | 
            |
| 20 | 
                + (4, u'合同签署完成'),  | 
            |
| 21 | 
                + (5, u'合同流签(合同过期)'),  | 
            |
| 22 | 
                + (6, u'合同撤回'),  | 
            |
| 23 | 
                + (8, u'合同待填写'),  | 
            |
| 24 | 
                + (21, u'解除协议(已解除)'),  | 
            |
| 25 | 
                + (16, u'合同已失效'),  | 
            |
| 26 | 
                + )  | 
            |
| 27 | 
                +  | 
            |
| 28 | 
                + APPROVE_STATUS_TYPE = (  | 
            |
| 29 | 
                + (2, u'待签署'),  | 
            |
| 30 | 
                + (7, u'待签署'),  | 
            |
| 31 | 
                + (3, u'已签署'),  | 
            |
| 32 | 
                + (4, u'拒绝'),  | 
            |
| 33 | 
                + (5, u'过期没人处理'),  | 
            |
| 34 | 
                + (6, u'流程已撤回'),  | 
            |
| 35 | 
                + (8, u'合同待填写'),  | 
            |
| 36 | 
                + (9, u'流程已终止'),  | 
            |
| 37 | 
                + (10, u'填写完成'),  | 
            |
| 38 | 
                + (15, u'解除协议(已解除)'),  | 
            |
| 39 | 
                + (15, u'已转他人处理'),  | 
            |
| 40 | 
                + )  | 
            |
| 41 | 
                +  | 
            |
| 42 | 
                + contract_id = ShortUUIDField(_(u'contract_id'), max_length=32, blank=True, null=True, help_text=u'合同唯一标识', db_index=True, unique=True)  | 
            |
| 43 | 
                +  | 
            |
| 44 | 
                + user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)  | 
            |
| 45 | 
                + lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)  | 
            |
| 46 | 
                +  | 
            |
| 47 | 
                + activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True)  | 
            |
| 48 | 
                + contribution_id = models.CharField(_(u'contribution_id'), max_length=32, blank=True, null=True, help_text=u'活动投稿唯一标识', db_index=True)  | 
            |
| 49 | 
                +  | 
            |
| 50 | 
                + contract_content_fields = JSONField(_(u'contract_content_fields'), blank=True, null=True, help_text=u' 合同内容字段')  | 
            |
| 51 | 
                + contract_file = models.FileField(_(u'contract_file'), upload_to=upload_path, blank=True, null=True, help_text=u'图片')  | 
            |
| 52 | 
                +  | 
            |
| 53 | 
                + # 电子签参数  | 
            |
| 54 | 
                + flow_id = models.CharField(_(u'flow_id'), max_length=128, blank=True, null=True, help_text=u'电子签流程ID')  | 
            |
| 55 | 
                + # 后续需用同样的FlowId再次调用发起签署流程,合同才能进入签署环节  | 
            |
| 56 | 
                + document_id = models.CharField(_(u'document_id'), max_length=128, blank=True, null=True, help_text=u'电子签文档ID')  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                + contract_status = models.IntegerField(_(u'contract_status'), choices=CONTRACT_STATUS_TUPLE, default=1, help_text=u'合同签署状态', db_index=True)  | 
            |
| 59 | 
                + approve_status = models.IntegerField(_(u'approve_status'), choices=APPROVE_STATUS_TYPE, default=2, help_text=u'签署人签署状态', db_index=True)  | 
            |
| 60 | 
                +  | 
            |
| 61 | 
                + class Meta:  | 
            |
| 62 | 
                + verbose_name = _(u'摄影师投稿合同信息')  | 
            |
| 63 | 
                + verbose_name_plural = _(u'摄影师投稿合同信息')  | 
            |
| 64 | 
                +  | 
            |
| 65 | 
                + def __unicode__(self):  | 
            |
| 66 | 
                + return '%d' % self.pk  | 
            |
| 67 | 
                +  | 
            |
| 68 | 
                + @property  | 
            |
| 69 | 
                + def contract_file_url(self):  | 
            |
| 70 | 
                + return qiniu_file_url(self.contract_file.name, bucket='tamron')  | 
            |
| 71 | 
                +  | 
            |
| 72 | 
                + @property  | 
            |
| 73 | 
                + def data(self):  | 
            |
| 74 | 
                +        return {
               | 
            |
| 75 | 
                + 'contract_id': self.contract_id,  | 
            |
| 76 | 
                + 'lensman_id': self.lensman_id,  | 
            |
| 77 | 
                + 'activity_id': self.activity_id,  | 
            |
| 78 | 
                + 'contribution_id': self.contribution_id,  | 
            |
| 79 | 
                + 'contract_content_fields': self.contract_content_fields,  | 
            |
| 80 | 
                + 'contract_file_url': self.contract_file_url,  | 
            |
| 81 | 
                + 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d %H:%M:%S'),  | 
            |
| 82 | 
                + 'updated_at': tc.local_string(utc_dt=self.updated_at, format='%Y-%m-%d %H:%M:%S')  | 
            |
| 83 | 
                + }  | 
            |
| 84 | 
                +  | 
            |
| 85 | 
                + @property  | 
            |
| 86 | 
                + def admindata(self):  | 
            |
| 87 | 
                + return self.data  | 
            |
| 88 | 
                +  | 
            |
| 89 | 
                + @property  | 
            |
| 90 | 
                + def mpdata(self):  | 
            |
| 91 | 
                + return self.data  | 
            
                @@ -0,0 +1,3 @@  | 
            ||
| 1 | 
                +from django.test import TestCase  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Create your tests here.  | 
            
                @@ -0,0 +1,3 @@  | 
            ||
| 1 | 
                +from django.shortcuts import render  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Create your views here.  | 
            
                @@ -0,0 +1,3 @@  | 
            ||
| 1 | 
                +from django.contrib import admin  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Register your models here.  | 
            
                @@ -0,0 +1,6 @@  | 
            ||
| 1 | 
                +from django.apps import AppConfig  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +class ActivityConfig(AppConfig):  | 
            |
| 5 | 
                + default_auto_field = 'django.db.models.BigAutoField'  | 
            |
| 6 | 
                + name = 'apps.lensman.activity'  | 
            
                @@ -0,0 +1,32 @@  | 
            ||
| 1 | 
                +# Generated by Django 3.2.8 on 2024-08-09 04:36  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import migrations, models  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +class Migration(migrations.Migration):  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                + initial = True  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.CreateModel(  | 
            |
| 15 | 
                + name='LensmanContributionActivityIncomeExpensesInfo',  | 
            |
| 16 | 
                + fields=[  | 
            |
| 17 | 
                +                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 18 | 
                +                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 19 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 20 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 21 | 
                +                ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
               | 
            |
| 22 | 
                +                ('lensman_id', models.CharField(blank=True, db_index=True, help_text='摄影师唯一标识', max_length=32, null=True, verbose_name='lensman_id')),
               | 
            |
| 23 | 
                +                ('activity_id', models.CharField(blank=True, db_index=True, help_text='活动唯一标识', max_length=32, null=True, verbose_name='activity_id')),
               | 
            |
| 24 | 
                +                ('contribution_id', models.CharField(blank=True, db_index=True, help_text='活动投稿唯一标识', max_length=32, null=True, verbose_name='contribution_id')),
               | 
            |
| 25 | 
                +                ('amount', models.IntegerField(default=0, help_text='金额(分)', verbose_name='amount')),
               | 
            |
| 26 | 
                + ],  | 
            |
| 27 | 
                +            options={
               | 
            |
| 28 | 
                + 'verbose_name': '摄影师投稿活动收入费用信息',  | 
            |
| 29 | 
                + 'verbose_name_plural': '摄影师投稿活动收入费用信息',  | 
            |
| 30 | 
                + },  | 
            |
| 31 | 
                + ),  | 
            |
| 32 | 
                + ]  | 
            
                @@ -0,0 +1,37 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import models  | 
            |
| 4 | 
                +from django.utils.translation import ugettext_lazy as _  | 
            |
| 5 | 
                +from django_models_ext import BaseModelMixin  | 
            |
| 6 | 
                +from TimeConvert import TimeConvert as tc  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class LensmanContributionActivityIncomeExpensesInfo(BaseModelMixin):  | 
            |
| 9 | 
                + user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)  | 
            |
| 10 | 
                + lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True)  | 
            |
| 13 | 
                + contribution_id = models.CharField(_(u'contribution_id'), max_length=32, blank=True, null=True, help_text=u'活动投稿唯一标识', db_index=True)  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + amount = models.IntegerField(_(u'amount'), default=0, help_text=u'金额(分)')  | 
            |
| 16 | 
                +  | 
            |
| 17 | 
                + class Meta:  | 
            |
| 18 | 
                + verbose_name = _(u'摄影师投稿活动收入费用信息')  | 
            |
| 19 | 
                + verbose_name_plural = _(u'摄影师投稿活动收入费用信息')  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                + def __unicode__(self):  | 
            |
| 22 | 
                + return '%d' % self.pk  | 
            |
| 23 | 
                +  | 
            |
| 24 | 
                + @property  | 
            |
| 25 | 
                + def data(self):  | 
            |
| 26 | 
                +        return {
               | 
            |
| 27 | 
                + 'lensman_id': self.lensman_id,  | 
            |
| 28 | 
                + 'activity_id': self.activity_id,  | 
            |
| 29 | 
                + 'contribution_id': self.contribution_id,  | 
            |
| 30 | 
                + 'amount': self.amount,  | 
            |
| 31 | 
                + 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d %H:%M:%S'),  | 
            |
| 32 | 
                + 'updated_at': tc.local_string(utc_dt=self.updated_at, format='%Y-%m-%d %H:%M:%S')  | 
            |
| 33 | 
                + }  | 
            |
| 34 | 
                +  | 
            |
| 35 | 
                + @property  | 
            |
| 36 | 
                + def admindata(self):  | 
            |
| 37 | 
                + return self.data  | 
            
                @@ -0,0 +1,3 @@  | 
            ||
| 1 | 
                +from django.test import TestCase  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Create your tests here.  | 
            
                @@ -0,0 +1,3 @@  | 
            ||
| 1 | 
                +from django.shortcuts import render  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Create your views here.  | 
            
                @@ -74,6 +74,8 @@ INSTALLED_APPS = (  | 
            ||
| 74 | 74 | 
                'statistic',  | 
            
| 75 | 75 | 
                'tenancy',  | 
            
| 76 | 76 | 
                'website',  | 
            
| 77 | 
                + 'apps.contract',  | 
            |
| 78 | 
                + 'apps.lensman.activity'  | 
            |
| 77 | 79 | 
                )  | 
            
| 78 | 80 | 
                 | 
            
| 79 | 81 | 
                 INSTALLED_APPS += ('multidomain', )
               | 
            
                @@ -262,9 +264,12 @@ QINIU = {
               | 
            ||
| 262 | 264 | 
                # 图片链接设置  | 
            
| 263 | 265 | 
                FILE_URL_TYPE = 'AUTO' # QINIU / SERVER / AUTO  | 
            
| 264 | 266 | 
                QINIU_FILE_URL_HTTPS = True  | 
            
| 265 | 
                -QINIU_FILE_URL_BEFORE = 'https://img.tamron.kodo.com.cn' # QINIU_FILE_URL_HTTPS False 时必填  | 
            |
| 266 | 
                -QINIU_FILE_URL_BEFORE2 = 'https://img.tamron.kodo.com.cn' # QINIU_FILE_URL_HTTPS False 时必填  | 
            |
| 267 | 
                -QINIU_FILE_URL_AFTER = 'http://img.tamron.kodo.com.cn' # QINIU_FILE_URL_HTTPS False 时必填  | 
            |
| 267 | 
                +# QINIU_FILE_URL_HTTPS False 时必填  | 
            |
| 268 | 
                +QINIU_FILE_URL_BEFORE = 'https://img.tamron.kodo.com.cn'  | 
            |
| 269 | 
                +# QINIU_FILE_URL_HTTPS False 时必填  | 
            |
| 270 | 
                +QINIU_FILE_URL_BEFORE2 = 'https://img.tamron.kodo.com.cn'  | 
            |
| 271 | 
                +# QINIU_FILE_URL_HTTPS False 时必填  | 
            |
| 272 | 
                +QINIU_FILE_URL_AFTER = 'http://img.tamron.kodo.com.cn'  | 
            |
| 268 | 273 | 
                 | 
            
| 269 | 274 | 
                # 图片设置  | 
            
| 270 | 275 | 
                # https://docs.djangoproject.com/en/5.0/releases/1.10/#maximum-size-of-a-request-body-and-the-number-of-get-post-parameters-is-limited  | 
            
                @@ -280,10 +285,12 @@ CURTAIL_UUID_LENGTH = 7 # Used in django-curtail-uuid==1.0.0  | 
            ||
| 280 | 285 | 
                 | 
            
| 281 | 286 | 
                # 水印设置  | 
            
| 282 | 287 | 
                WATERMARK_OR_NOT = False # 水印是否开启  | 
            
| 283 | 
                -WATERMARK_LOGO_PATH = os.path.join(PROJ_DIR, 'static/kodo/img/paiai_water_mark.png').replace('\\', '/')  # 水印图片路径
               | 
            |
| 288 | 
                +WATERMARK_LOGO_PATH = os.path.join(  | 
            |
| 289 | 
                +    PROJ_DIR, 'static/kodo/img/paiai_water_mark.png').replace('\\', '/')  # 水印图片路径
               | 
            |
| 284 | 290 | 
                 | 
            
| 285 | 291 | 
                # 原图设置  | 
            
| 286 | 
                -LENSMAN_PHOTO_ORIGIN_EXPIRED_MSEL = 604800000 # 摄影师原图过期毫秒数,7d = 7 * 24 * 3600 * 1000msel  | 
            |
| 292 | 
                +# 摄影师原图过期毫秒数,7d = 7 * 24 * 3600 * 1000msel  | 
            |
| 293 | 
                +LENSMAN_PHOTO_ORIGIN_EXPIRED_MSEL = 604800000  | 
            |
| 287 | 294 | 
                 | 
            
| 288 | 295 | 
                # 缩略图设置  | 
            
| 289 | 296 | 
                THUMBNAIL_MAX_WIDTH = 540  | 
            
                @@ -292,19 +299,27 @@ THUMBNAIL_MAX_WIDTH2 = 1080  | 
            ||
| 292 | 299 | 
                # 首页设置  | 
            
| 293 | 300 | 
                PAI2_HOME_PER_PAGE = 20 # 首页照片每页数量  | 
            
| 294 | 301 | 
                PAI2_HOME_MAX_PAGE = 20 # 首页照片最大页数  | 
            
| 295 | 
                -PAI2_HOME_MAX_ROWS = 400 # 首页照片最大数量,PAI2_HOME_PER_PAGE * PAI2_HOME_MAX_PAGE = 20 * 20 = 400  | 
            |
| 302 | 
                +# 首页照片最大数量,PAI2_HOME_PER_PAGE * PAI2_HOME_MAX_PAGE = 20 * 20 = 400  | 
            |
| 303 | 
                +PAI2_HOME_MAX_ROWS = 400  | 
            |
| 296 | 304 | 
                 | 
            
| 297 | 305 | 
                # 下载页设置  | 
            
| 298 | 
                -TMPL_DOWNLOAD_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/download.tmpl.html').replace('\\', '/')
               | 
            |
| 306 | 
                +TMPL_DOWNLOAD_PAGE_PATH = os.path.join(  | 
            |
| 307 | 
                +    BASE_DIR, 'page/templates/page/download.tmpl.html').replace('\\', '/')
               | 
            |
| 299 | 308 | 
                 | 
            
| 300 | 
                -PAI2_USER_DOWNLOAD_ADR_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_user_adr_download.html').replace('\\', '/')
               | 
            |
| 301 | 
                -PAI2_USER_DOWNLOAD_IOS_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_user_ios_download.html').replace('\\', '/')
               | 
            |
| 309 | 
                +PAI2_USER_DOWNLOAD_ADR_PAGE_PATH = os.path.join(  | 
            |
| 310 | 
                +    BASE_DIR, 'page/templates/page/kodo_user_adr_download.html').replace('\\', '/')
               | 
            |
| 311 | 
                +PAI2_USER_DOWNLOAD_IOS_PAGE_PATH = os.path.join(  | 
            |
| 312 | 
                +    BASE_DIR, 'page/templates/page/kodo_user_ios_download.html').replace('\\', '/')
               | 
            |
| 302 | 313 | 
                 | 
            
| 303 | 
                -PAI2_LENSMAN_DOWNLOAD_ADR_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_lensman_adr_download.html').replace('\\', '/')
               | 
            |
| 304 | 
                -PAI2_LENSMAN_DOWNLOAD_IOS_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_lensman_ios_download.html').replace('\\', '/')
               | 
            |
| 314 | 
                +PAI2_LENSMAN_DOWNLOAD_ADR_PAGE_PATH = os.path.join(  | 
            |
| 315 | 
                +    BASE_DIR, 'page/templates/page/kodo_lensman_adr_download.html').replace('\\', '/')
               | 
            |
| 316 | 
                +PAI2_LENSMAN_DOWNLOAD_IOS_PAGE_PATH = os.path.join(  | 
            |
| 317 | 
                +    BASE_DIR, 'page/templates/page/kodo_lensman_ios_download.html').replace('\\', '/')
               | 
            |
| 305 | 318 | 
                 | 
            
| 306 | 
                -PAI2_TOURGUIDE_DOWNLOAD_ADR_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_tourguide_adr_download.html').replace('\\', '/')
               | 
            |
| 307 | 
                -PAI2_TOURGUIDE_DOWNLOAD_IOS_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_tourguide_ios_download.html').replace('\\', '/')
               | 
            |
| 319 | 
                +PAI2_TOURGUIDE_DOWNLOAD_ADR_PAGE_PATH = os.path.join(  | 
            |
| 320 | 
                +    BASE_DIR, 'page/templates/page/kodo_tourguide_adr_download.html').replace('\\', '/')
               | 
            |
| 321 | 
                +PAI2_TOURGUIDE_DOWNLOAD_IOS_PAGE_PATH = os.path.join(  | 
            |
| 322 | 
                +    BASE_DIR, 'page/templates/page/kodo_tourguide_ios_download.html').replace('\\', '/')
               | 
            |
| 308 | 323 | 
                 | 
            
| 309 | 324 | 
                # 下载设置  | 
            
| 310 | 325 | 
                PAI2_USER_DOWNLOAD_WX_URL = 'https://a.app.qq.com/o/simple.jsp?pkgname=ai.pai.client'  | 
            
                @@ -490,7 +505,8 @@ WEBSITE_MOBI = '{0}/pc/'.format(DOMAIN)
               | 
            ||
| 490 | 505 | 
                 | 
            
| 491 | 506 | 
                # 依赖 local_settings 中的配置  | 
            
| 492 | 507 | 
                # 微信授权设置  | 
            
| 493 | 
                -WECHAT_OAUTH2_REDIRECT_URI = '{0}/we/we_oauth2?scope={{0}}redirect_url={{1}}'.format(DOMAIN_HTTP)
               | 
            |
| 508 | 
                +WECHAT_OAUTH2_REDIRECT_URI = '{0}/we/we_oauth2?scope={{0}}redirect_url={{1}}'.format(
               | 
            |
| 509 | 
                + DOMAIN_HTTP)  | 
            |
| 494 | 510 | 
                 WECHAT_BASE_REDIRECT_URI = '{0}/we/base_redirect'.format(DOMAIN_HTTP)
               | 
            
| 495 | 511 | 
                 WECHAT_USERINFO_REDIRECT_URI = '{0}/we/userinfo_redirect'.format(DOMAIN_HTTP)
               | 
            
| 496 | 512 | 
                 | 
            
                @@ -500,13 +516,18 @@ SYSTEM_MESSAGE_AVATAR = PAI2_LOGO_URL  | 
            ||
| 500 | 516 | 
                COMMENT_MESSAGE_AVATAR = PAI2_LOGO_URL  | 
            
| 501 | 517 | 
                THUMBUP_MESSAGE_AVATAR = PAI2_LOGO_URL  | 
            
| 502 | 518 | 
                 | 
            
| 503 | 
                -KODO_CLERK_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fclerk%3Fbrand_id%3D{{0}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
               | 
            |
| 504 | 
                -KODO_SCREEN_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Foauth%3Fbrand_id%3D{{0}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
               | 
            |
| 505 | 
                -KODO_SCREEN_LOGIN_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Flogin%3Fbrand_id%3D{{0}}%26token%3D{{1}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
               | 
            |
| 519 | 
                +KODO_CLERK_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fclerk%3Fbrand_id%3D{{0}}'.format(
               | 
            |
| 520 | 
                + OAUTH_DOMAIN, BASE_DOMAIN)  | 
            |
| 521 | 
                +KODO_SCREEN_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Foauth%3Fbrand_id%3D{{0}}'.format(
               | 
            |
| 522 | 
                + OAUTH_DOMAIN, BASE_DOMAIN)  | 
            |
| 523 | 
                +KODO_SCREEN_LOGIN_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Flogin%3Fbrand_id%3D{{0}}%26token%3D{{1}}'.format(
               | 
            |
| 524 | 
                + OAUTH_DOMAIN, BASE_DOMAIN)  | 
            |
| 506 | 525 | 
                 | 
            
| 507 | 
                -KODO_SUPERSR_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fsupersr%2Foauth%3Fbrand_id%3D{{0}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
               | 
            |
| 526 | 
                +KODO_SUPERSR_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fsupersr%2Foauth%3Fbrand_id%3D{{0}}'.format(
               | 
            |
| 527 | 
                + OAUTH_DOMAIN, BASE_DOMAIN)  | 
            |
| 508 | 528 | 
                 | 
            
| 509 | 
                -DJANGO_WE_COMPONENT_REDIRECT_URI = '{0}/we/component_preauth'.format(PREAUTH_DOMAIN)
               | 
            |
| 529 | 
                +DJANGO_WE_COMPONENT_REDIRECT_URI = '{0}/we/component_preauth'.format(
               | 
            |
| 530 | 
                + PREAUTH_DOMAIN)  | 
            |
| 510 | 531 | 
                 | 
            
| 511 | 532 | 
                # Redis 连接  | 
            
| 512 | 533 | 
                 REDIS_CACHE = connector(REDIS.get('default', {}))
               | 
            
                @@ -569,3 +590,7 @@ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'  | 
            ||
| 569 | 590 | 
                 | 
            
| 570 | 591 | 
                DEFAULT_START_DATE = '1970-01-02'  | 
            
| 571 | 592 | 
                DEFAULT_END_DATE = '9999-12-03'  | 
            
| 593 | 
                +  | 
            |
| 594 | 
                +# 腾讯电子签配置  | 
            |
| 595 | 
                +CONTRACT_LENSMAN_CONTRIBUTION_TEMPLATE_ID = 'yDCp3UU05rgksnUXtZsEvdrK1tRGb7ax'  | 
            |
| 596 | 
                +CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID = 'yDCp3UU055m70lUx6jaTk1RVkiVkKenJ'  |